﻿using System;
using System.Collections.Generic;
using System.Linq;
using Controller2.Models;
using System.Data;

namespace Controller2.BLL
{
    public class ClienteBll
    {
        /// <summary>
        /// Retorna um cadastro de cliente de acordo com o IdPessoa
        /// </summary>
        /// <param name="db">Contexto de dados</param>
        /// <param name="id">IdPessoa</param>
        /// <returns>Pessoa</returns>
        public static Pessoa GetCliente(ControllerBDModelContainer db, int id)
        {
            var cli = db.Pessoa.Where(p => p.TipoPessoa.Select(tp => tp.Tipo).FirstOrDefault().Equals("Cliente") && p.IdPessoa == id).FirstOrDefault();
            return cli;
        }

        /// <summary>
        /// Retorna um cadastro de cliente de acordo com o nome de usuario
        /// </summary>
        /// <param name="db">Contexto de dados</param>
        /// <param name="username">Username</param>
        /// <returns>Pessoa</returns>
        public static Pessoa GetCliente(ControllerBDModelContainer db, string username)
        {
            var cli = db.Pessoa.FirstOrDefault(p => p.UserName == username &&
                p.TipoPessoa.Select(t => t.Tipo) == db.TipoPessoa.Select(tp => tp.Tipo).Where(tp => tp.Equals("Cliente")));
            return cli;
        }

        public static Pessoa_PF GetClientePF(ControllerBDModelContainer db, int id)
        {
            var cli = db.Pessoa.OfType<Pessoa_PF>().FirstOrDefault(p => p.IdPessoa == id &&
                p.TipoPessoa.Select(t => t.Tipo) == db.TipoPessoa.Select(tp => tp.Tipo).Where(tp => tp.Equals("Cliente")));
            return cli;
        }

        public static Pessoa_PJ GetClientePJ(ControllerBDModelContainer db, int id)
        {
            var cli = db.Pessoa.OfType<Pessoa_PJ>().FirstOrDefault(p => p.IdPessoa == id &&
                p.TipoPessoa.Select(t => t.Tipo) == db.TipoPessoa.Select(tp => tp.Tipo).Where(tp => tp.Equals("Cliente")));
            return cli;
        }

        public static IEnumerable<Pessoa> GetAllClientes(ControllerBDModelContainer db)
        {
            var cli = from t in db.TipoPessoa
                      where t.Tipo.Equals("Cliente")
                      from p in t.Pessoa
                      select p;
            return cli;
        }

        /// <summary>
        /// Faz o autocomplete do campo de texto de pesquisa
        /// </summary>
        /// <param name="db">Contexto de dados</param>
        /// <param name="filtro">Valor do filtro (combobox)</param>
        /// <param name="termoPesquisa">Termo da pesquisa (valor digitado)</param>
        /// <param name="numeroLinhas">Número de registros a serem mostrados</param>
        /// <returns></returns>
        public static IEnumerable<string> AutoComplete(ControllerBDModelContainer db, int filtro, string termoPesquisa, int numeroLinhas)
        {
            IEnumerable<string> resultado;
            int codigo = 0;
            if (filtro == 1)
            {
                if (!int.TryParse(termoPesquisa, out codigo))
                {
                    filtro = 2;
                }
            }
            switch (filtro)
            {
                default:
                    resultado = (from t in db.TipoPessoa.ToList()
                                 where t.Tipo.Equals("Cliente")
                                 from p in t.Pessoa
                                 where p.IdPessoa >= codigo
                                 select p.IdPessoa.ToString()).Distinct();
                    break;
                case 2:
                    resultado = (from t in db.TipoPessoa
                                 where t.Tipo.Equals("Cliente")
                                 from p in t.Pessoa
                                 where p.NomePessoa.Contains(termoPesquisa)
                                 select p.NomePessoa).Distinct();
                    break;
                case 3:
                    resultado = (from t in db.TipoPessoa
                                 where t.Tipo.Equals("Cliente")
                                 from p in t.Pessoa
                                 where p.Email.Contains(termoPesquisa)
                                 select p.Email).Distinct();
                    break;
                case 4:
                    resultado = (from t in db.TipoPessoa
                                 where t.Tipo.Equals("Cliente")
                                 from p in t.Pessoa
                                 where p.Cidade.NomeCidade.Contains(termoPesquisa)
                                 select p.Cidade.NomeCidade).Distinct();
                    break;
            }
            return resultado.Take(numeroLinhas);
        }

        /// <summary>
        /// Faz o autocomplete do campo de texto de pesquisa
        /// </summary>
        /// <param name="db">Contexto de dados</param>
        /// <param name="termoPesquisa">Termo da pesquisa (valor digitado)</param>
        /// <param name="numeroLinhas">Número de registros a serem mostrados</param>
        /// <returns></returns>
        public static IEnumerable<string> AutoComplete(ControllerBDModelContainer db, string termoPesquisa, int numeroLinhas)
        {
            IEnumerable<string> resultado;
            int codigo = 0;
            if (Int32.TryParse(termoPesquisa, out codigo))
            {
                return resultado = (from t in db.TipoPessoa.ToList()
                                    where t.Tipo.Equals("Cliente")
                                    from p in t.Pessoa
                                    where p.IdPessoa >= codigo
                                    select p.IdPessoa.ToString()).Distinct().Take(numeroLinhas);
            }
            else
            {
                return resultado = (from t in db.TipoPessoa
                                    where t.Tipo.Equals("Cliente")
                                    from p in t.Pessoa
                                    where p.NomePessoa.Contains(termoPesquisa)
                                    select p.NomePessoa).Distinct().Take(numeroLinhas);
            }
        }

        public static string BuscaNomeCliente(ControllerBDModelContainer db, int id)
        {
            var dados = (from t in db.TipoPessoa.ToList()
                         where t.Tipo.Equals("Cliente")
                         from p in t.Pessoa
                         where p.IdPessoa >= id
                         select p.NomePessoa).FirstOrDefault().ToString();
            return dados;
        }

        public static DataTable Relatorios(ControllerBDModelContainer db, int codigo, string dataInicial, string dataFinal)
        {
            IEnumerable<Pessoa> lista;
            if (codigo > 0)
            {
                lista = (
                    from t in db.TipoPessoa
                    where t.Tipo.Equals("Cliente")
                    from p in t.Pessoa
                    where p.IdPessoa == codigo
                    select p
                ).ToList().OrderBy(c => c.DataCadastro);
            }
            else if (!string.IsNullOrWhiteSpace(dataInicial))
            {
                var di = Convert.ToDateTime(dataInicial);
                var df = Convert.ToDateTime(dataFinal);
                lista = (
                    from t in db.TipoPessoa
                    where t.Tipo.Equals("Cliente")
                    from p in t.Pessoa
                    where p.DataCadastro >= di && p.DataCadastro <= df
                    select p
                ).OrderBy(c => c.DataCadastro).ToList();
            }
            else
            {
                lista = (
                    from t in db.TipoPessoa
                    where t.Tipo.Equals("Cliente")
                    from p in t.Pessoa
                    select p
                ).OrderBy(c => c.DataCadastro).ToList();
            }

            var dt = new DataTable();
            dt.Columns.Add("DataCadastro", typeof(DateTime));
            dt.Columns.Add("IdPessoa", typeof(Int32));
            dt.Columns.Add("Nome", typeof(String));
            dt.Columns.Add("Email", typeof(String));            
            dt.Columns.Add("Cidade", typeof(String));
            dt.Columns.Add("Estado", typeof(String));
            dt.Columns.Add("Fone", typeof(String));

            foreach (Pessoa p in lista)
            {
                DataRow r = dt.NewRow();
                r["DataCadastro"] = p.DataCadastro;
                r["IdPessoa"] = p.IdPessoa;
                r["Nome"] = p.NomePessoa;
                r["Email"] = p.Email;
                r["Cidade"] = p.Cidade.NomeCidade;
                r["Estado"] = p.Cidade.Estado.NomeEstado;
                r["Fone"] = p.Fone;
                dt.Rows.Add(r);
            }
            return dt;
        }
    }
}